package com.example.zkdemo;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.concurrent.CountDownLatch;

public class MyZkConnect {

    private static Logger logger = LoggerFactory.getLogger(MyZkConnect.class);

    private static final String zkServer = "localhost:2181";

    public static final int timeout = 3000;


    /**
     * 建立连接
     * **/
    public static ZooKeeper connect(){

        CountDownLatch latch = new CountDownLatch(1);
        logger.info("准备建立ZK服务连接");
        ZooKeeper zooKeeper = null;
        try{
            zooKeeper = new ZooKeeper(zkServer, timeout, new Watcher() {
               @Override
               public void process(WatchedEvent watchedEvent) {
                    logger.info("watch监听事件:{}",watchedEvent);
                    latch.countDown();
               }
            });
            latch.await();
        }catch (Exception e ){
           logger.error("创建ZK连接失败：",e);
        }
        return zooKeeper;
    }

    /**
     * 创建节点
     * **/
    public static void create(ZooKeeper zooKeeper,String nodePath,String nodeData){
        logger.info("开始创建节点：{}，数据：{}",nodePath,nodeData);
        List<ACL> acls = ZooDefs.Ids.OPEN_ACL_UNSAFE;

        CreateMode createMode = CreateMode.PERSISTENT;
        try {
            String result = zooKeeper.create(nodePath,nodeData.getBytes(),acls,createMode);
        }catch (Exception e){
            logger.error("创建节点失败",e);
        }
    }

    /**
     * 查询节点结构信息
     * **/
    public static Stat queryStat(ZooKeeper zooKeeper,String nodePath){
        logger.info("准备查询节点：{}",nodePath);
        Stat stat = null;
        try{
            stat = zooKeeper.exists(nodePath,false);
        }catch (Exception e){
            logger.error("查询节点结构信息失败",e);
        }
        return stat;
    }

    /**
     * 查询节点Data信息
     * **/
    public static String queryData(ZooKeeper zooKeeper,String nodePath){
        logger.info("准备查询节点数据：{}",nodePath);
        String nodeData = null;
        try{
            nodeData = new String(zooKeeper.getData(nodePath,false,queryStat(zooKeeper,nodePath)));
        }catch (Exception e){
            logger.error("查询节点数据失败",e);
        }
        return nodeData;
    }

    /**
     * 修改节点
     * **/
    public static Stat update(ZooKeeper zooKeeper,String nodePath,String nodeData){
        //修改前查询该节点信息
        Stat stat = queryStat(zooKeeper,nodePath);
        logger.info("准备修改节点");
        try{
            Stat newStat = zooKeeper.setData(nodePath,nodeData.getBytes(),stat.getVersion());
        }catch (Exception e){
            logger.error("修改节点数据失败",e);
        }
        return stat;
    }

    public static void delete(ZooKeeper zooKeeper,String nodePath){
        //删除前先查询该节点信息
        Stat stat = queryStat(zooKeeper,nodePath);
        logger.info("准备删除节点");
        try{
            zooKeeper.delete(nodePath,stat.getVersion());
        }catch (Exception e){
            logger.error("删除节点失败",e);
        }
    }


    public static void main(String[] args){

        ZooKeeper zooKeeper = connect();


        String nodeData = queryData(zooKeeper,"/tst");
        logger.info("节点数据：{}",nodeData);
        System.out.println(nodeData);
    }
}
